#include"index.hpp"
#include"util.hpp"
#include<algorithm>
#include<jsoncpp/json/json.h>


namespace us_searcher
{
    class Searcher
    {
        private:
        us_index::Index* index;

        public:
        Searcher(){};
        ~Searcher(){};

        public:
        void InitSearcher(const std::string& src) //根据之前的二进制文件构建索引
        {
            index=us_index::Index::GetInstance();
            index->BuildIndex(src);
        }

        void Search(const std::string& query,std::string* string_json)
        {
            // 根据输入进行分词
            std::vector<std::string> words;
            us_util::JiebaUtil::CutString(query,&words);

            // 大小写转换，建立倒排拉链
            us_index::InvertedList inverted_list;
            for(auto word:words)
            {
                auto inverted = index->GetInvertedIndex(word);// 根据分词获取倒排拉链

                if(inverted == nullptr) //如果倒排为空
                {
                    continue;
                }
                //插入,但是直接这样子写会造成重复
                inverted_list.insert(inverted_list.end(),inverted->begin(),inverted->end());
            }

            // 根据weight进行降序排序
            std::sort(inverted_list.begin(),inverted_list.end(),[](const us_index::InvertedElem& e1, const us_index::InvertedElem& e2){
                return e1.weight>e2.weight;
            });

            // 构建并返回json
            Json::Value root;
            for(auto& item : inverted_list)
            {
                us_index::DocInfo* doc = index->GetForwardIndex(item.doc_id);
                Json::Value elem;
                elem["title"]=doc->title;//标题
                elem["desc"]=GetDesc(doc->content,item.word);//概要(这里不是主体内容)
                elem["url"]=doc->url;
                root.append(elem);
            }
            Json::FastWriter writer;
            *string_json=writer.write(root);
            
        }

        std::string GetDesc(const std::string& content,const std::string& word)
        {
            //第一步：找到word在content出现的位置
            auto iter = std::search(content.begin(),content.end(),word.begin(),word.end(),[](int x,int y){
                return std::tolower(x)==std::tolower(y);
            });
            if(iter==content.end())
            {
                return "None1";
            }
            int pos = std::distance(content.begin(),iter);

            int start=0,end=content.size()-1;//这里不用size_t是因为后续方便后续判断收尾条件 
            //第二步：从找到位置向前找50个向后找100个
            if(pos-50>start)
            {
                start=pos-50;
            }
            if(pos+100<end)
            {
                end=pos+100;
            }
            //第三步：切割并return

            if(end<=start)
            {
                return "None2";
            }
            return content.substr(start,end-start);
        }
    };
}
